package com.ywl.study.sharding.study07;

import org.apache.shardingsphere.shardingjdbc.api.yaml.YamlShardingDataSourceFactory;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class XAOrderService {
    private DataSource dataSource;

    XAOrderService(final String yamlConfigFile) throws IOException, SQLException {
        dataSource= YamlShardingDataSourceFactory.createDataSource(getFile(yamlConfigFile));
    }

    private File getFile(final String fileName){
        return new File(XAOrderService.class.getResource(fileName).getFile());
    }

//    void init() throws SQLException {
//        try(Connection connection=dataSource.getConnection()){
//            Statement statement=connection.createStatement();
//            statement.execute("DROP TABLE IF EXISTS t_order");
//            statement.execute("CREATE TABLE t_order (order_id BIGINT AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id))");
//        }
//    }


    void init() throws SQLException {
        try(Connection connection=dataSource.getConnection()){
            Statement statement=connection.createStatement();
            statement.execute("CREATE TABLE t_order (order_id BIGINT AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id)) ");
        }
    }
    void cleanup() throws SQLException {
        try (Connection connection = dataSource.getConnection()) {
            Statement statement = connection.createStatement();
            statement.execute("DROP TABLE IF EXISTS t_order");
        }
    }

    void insert() throws SQLException {
        TransactionTypeHolder.set(TransactionType.XA);
        try(Connection connection=dataSource.getConnection()){
            connection.setAutoCommit(false);
            PreparedStatement statement=connection.prepareStatement("INSERT INTO t_order (user_id, status) VALUES (?, ?)");
            doInsert(statement);
            connection.commit();
        }
    }


    void insertFailed() throws SQLException {
        TransactionTypeHolder.set(TransactionType.XA);
        try(Connection connection=dataSource.getConnection()){
            connection.setAutoCommit(false);
            PreparedStatement statement=connection.prepareStatement("INSERT INTO t_order (user_id, status) VALUES (?, ?)");
            doInsert(statement);
            connection.rollback();
        }
    }

    private void doInsert(final PreparedStatement preparedStatement) throws SQLException {
        for (int i = 0; i < 10; i++) {
            preparedStatement.setObject(1, i);
            preparedStatement.setObject(2, "init");
            preparedStatement.executeUpdate();
        }
    }

    /**
     * Select all.
     *
     * @return record count
     */
    int selectAll() throws SQLException {
        int result = 0;
        try (Connection connection = dataSource.getConnection()) {
            Statement statement = connection.createStatement();
            statement.executeQuery("SELECT COUNT(1) AS count FROM t_order");
            ResultSet resultSet = statement.getResultSet();
            while (resultSet.next()) {
                result = resultSet.getInt(1);
            }
        }
        return result;
    }

    String getMax() throws SQLException {
        String result="";
        try (Connection connection = dataSource.getConnection()) {
            Statement statement = connection.createStatement();
            statement.executeQuery("SELECT max(order_id) FROM t_order");
            ResultSet resultSet = statement.getResultSet();
            while (resultSet.next()) {
                result = resultSet.getString(1);
            }
        }
        return result;
    }

    void showData() throws SQLException {
        try (Connection connection = dataSource.getConnection()) {
            Statement statement = connection.createStatement();
            statement.executeQuery("SELECT *  FROM t_order order by order_id");
            ResultSet resultSet = statement.getResultSet();
            while (resultSet.next()) {
                String orerId= resultSet.getString(1);
                System.out.println(orerId);
            }
        }
    }



}
